﻿using MaterialDemo.DataEntity;
using MaterialDemo.DataEntity.Entities;
using MaterialDemo.IService.IPermission;
using MaterialDemo.IService.IWorkFlow;
using MaterialDemo.Model.DepartmentDTO;
using MaterialDemo.Model.Enum;
using MaterialDemo.Model.WorkFlowDTO;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MaterialDemo.Service.WorkFlow
{
    public class WorkFlowService: IWorkFlowService
    {
        #region 构造函数注入
        private readonly ILogger<WorkFlowService> _logger;
        private readonly DbContext _dbContext;
        private readonly IDepartmentService _departmentService;
        public WorkFlowService(ILogger<WorkFlowService> logger, DbContext dbcontext, IDepartmentService departmentService)
        {
            _logger = logger;
            _dbContext = dbcontext;
            _departmentService = departmentService;
        }


        #endregion

        public List<WorkFlowInstanceOutput> LoadPageEntitiesByReviewer(int pageIndex, int pageSize, out int totalCount, string nextReviewerId, bool isConsumable)
        {
          
            if (isConsumable)//说明是耗材模板
            {
                totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.NextReviewer == nextReviewerId && u.Status == (int)MyEnum.ConsumableStatus.InReview && u.ModelId == 2).Count();
                //注意：必须是审核中的状态的才行
                IQueryable<WorkFlowInstance> iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.NextReviewer == nextReviewerId && u.Status == (int)MyEnum.ConsumableStatus.InReview && u.ModelId == 2).OrderByDescending(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                var linq = from a in iquery
                           join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                           from c in join_a.DefaultIfEmpty()
                           join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                           from e in join_b.DefaultIfEmpty()
                           join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                           from g in join_c.DefaultIfEmpty()
                           join h in _dbContext.Set<GoodsConsumableInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                           from i in join_d.DefaultIfEmpty()
                           select new WorkFlowInstanceOutput
                           {
                               Id = a.Id,
                               AddTime = a.AddTime,
                               Description = a.Description,
                               ModelId = a.ModelId,
                               ModelName = g.Title,
                               InstanceId = a.InstanceId,

                               UserId = a.UserId,
                               UserName = c.UserName,
                               NextReviewer = a.NextReviewer,
                               ReviewerName = e.UserName,
                               OutGoodsName = i.Name,
                               OutNum = a.OutNum,
                               Reason = a.Reason,
                               Status = a.Status,
                           };
                return linq.ToList();
            }
            else
            {
                totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.NextReviewer == nextReviewerId && u.Status == (int)MyEnum.ConsumableStatus.InReview && u.ModelId == 3).Count();
                //注意：必须是审核中的状态的才行
                IQueryable<WorkFlowInstance> iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.NextReviewer == nextReviewerId && u.Status == (int)MyEnum.ConsumableStatus.InReview && u.ModelId == 3).OrderByDescending(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                var linq = from a in iquery
                           join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                           from c in join_a.DefaultIfEmpty()
                           join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                           from e in join_b.DefaultIfEmpty()
                           join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                           from g in join_c.DefaultIfEmpty()
                           join h in _dbContext.Set<GoodsEquipmentInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                           from i in join_d.DefaultIfEmpty()
                           select new WorkFlowInstanceOutput
                           {
                               Id = a.Id,
                               AddTime = a.AddTime,
                               Description = a.Description,
                               ModelId = a.ModelId,
                               ModelName = g.Title,
                               InstanceId = a.InstanceId,

                               UserId = a.UserId,
                               UserName = c.UserName,
                               NextReviewer = a.NextReviewer,
                               ReviewerName = e.UserName,
                               OutGoodsName = i.Name,
                               OutNum = a.OutNum,
                               Reason = a.Reason,
                               Status = a.Status,
                           };
                return linq.ToList();
            }
         
           
        }

        public List<WorkFlowInstanceOutput> LoadPageEntitiesByUserId(int pageIndex, int pageSize, out int totalCount, string userId, bool isConsumable)
        {
          
            if (isConsumable)
            {
                totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.UserId == userId && u.ModelId == 2).Count();
                IQueryable<WorkFlowInstance> iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.UserId == userId && u.ModelId == 2).OrderByDescending(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                var linq = from a in iquery
                           join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                           from c in join_a.DefaultIfEmpty()
                           join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                           from e in join_b.DefaultIfEmpty()
                           join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                           from g in join_c.DefaultIfEmpty()
                           join h in _dbContext.Set<GoodsConsumableInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                           from i in join_d.DefaultIfEmpty()
                           select new WorkFlowInstanceOutput
                           {
                               Id = a.Id,
                               AddTime = a.AddTime,
                               Description = a.Description,
                               ModelId = a.ModelId,
                               ModelName = g.Title,
                               InstanceId = a.InstanceId,

                               UserId = a.UserId,
                               UserName = c.UserName,
                               NextReviewer = a.NextReviewer,
                               ReviewerName = e.UserName,
                               OutGoodsName = i.Name,
                               OutNum = a.OutNum,
                               Reason = a.Reason,
                               Status = a.Status,
                           };
                return linq.ToList();
            }
            else
            {
                totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.UserId == userId && u.ModelId == 3).Count();
                IQueryable<WorkFlowInstance> iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.UserId == userId && u.ModelId == 3).OrderByDescending(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                var linq = from a in iquery
                           join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                           from c in join_a.DefaultIfEmpty()
                           join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                           from e in join_b.DefaultIfEmpty()
                           join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                           from g in join_c.DefaultIfEmpty()
                           join h in _dbContext.Set<GoodsEquipmentInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                           from i in join_d.DefaultIfEmpty()
                           select new WorkFlowInstanceOutput
                           {
                               Id = a.Id,
                               AddTime = a.AddTime,
                               Description = a.Description,
                               ModelId = a.ModelId,
                               ModelName = g.Title,
                               InstanceId = a.InstanceId,

                               UserId = a.UserId,
                               UserName = c.UserName,
                               NextReviewer = a.NextReviewer,
                               ReviewerName = e.UserName,
                               OutGoodsName = i.Name,
                               OutNum = a.OutNum,
                               Reason = a.Reason,
                               Status = a.Status,
                           };
                return linq.ToList();
            }
       
        }

        public List<WorkFlowInstanceOutput> LoadPageEntitiesByKeeper(int pageIndex, int pageSize, out int totalCount, string selectInfo, bool isConsumable)
        {


            if (isConsumable)
            {
                IQueryable<WorkFlowInstance> iquery;
                if (string.IsNullOrEmpty(selectInfo))
                {
                    totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.ConsumableStatus.IsPass&&u.ModelId==2).Count();
                    iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.ConsumableStatus.IsPass && u.ModelId == 2).OrderBy(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                }
                else
                {
                    totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.ConsumableStatus.IsPass && u.UserId == selectInfo && u.ModelId == 2).Count();
                    iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.ConsumableStatus.IsPass && u.UserId == selectInfo && u.ModelId == 2).OrderBy(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                }
                var linq = from a in iquery
                           join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                           from c in join_a.DefaultIfEmpty()
                           join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                           from e in join_b.DefaultIfEmpty()
                           join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                           from g in join_c.DefaultIfEmpty()
                           join h in _dbContext.Set<GoodsConsumableInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                           from i in join_d.DefaultIfEmpty()
                           select new WorkFlowInstanceOutput
                           {
                               Id = a.Id,
                               AddTime = a.AddTime,
                               Description = a.Description,
                               ModelId = a.ModelId,
                               ModelName = g.Title,
                               InstanceId = a.InstanceId,

                               UserId = a.UserId,
                               UserName = c.UserName,
                               NextReviewer = a.NextReviewer,
                               ReviewerName = e.UserName,
                               OutGoodsName = i.Name,
                               OutNum = a.OutNum,
                               Reason = a.Reason,
                               Status = a.Status,
                           };
                return linq.ToList();
            }
            else
            {
                IQueryable<WorkFlowInstance> iquery;
                if (string.IsNullOrEmpty(selectInfo))
                {
                    totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsPass && u.ModelId == 3).Count();
                    iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsPass && u.ModelId == 3).OrderBy(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                }
                else
                {
                    totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsPass && u.UserId == selectInfo && u.ModelId == 3).Count();
                    iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsPass && u.UserId == selectInfo && u.ModelId == 3).OrderBy(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                }
                var linq = from a in iquery
                           join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                           from c in join_a.DefaultIfEmpty()
                           join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                           from e in join_b.DefaultIfEmpty()
                           join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                           from g in join_c.DefaultIfEmpty()
                           join h in _dbContext.Set<GoodsEquipmentInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                           from i in join_d.DefaultIfEmpty()
                           select new WorkFlowInstanceOutput
                           {
                               Id = a.Id,
                               AddTime = a.AddTime,
                               Description = a.Description,
                               ModelId = a.ModelId,
                               ModelName = g.Title,
                               InstanceId = a.InstanceId,

                               UserId = a.UserId,
                               UserName = c.UserName,
                               NextReviewer = a.NextReviewer,
                               ReviewerName = e.UserName,
                               OutGoodsName = i.Name,
                               OutNum = a.OutNum,
                               Reason = a.Reason,
                               Status = a.Status,
                           };
                return linq.ToList();
            }



      
        }

        public WorkFlowInstanceOutput LoadInstanceEntitiy(int Id)
        {
            var entity = _dbContext.Set<WorkFlowInstance>().Find(Id);

            return new WorkFlowInstanceOutput
            {
                Id = entity.Id,
                AddTime = entity.AddTime,
                Description = entity.Description,
                ModelId = entity.ModelId,
                InstanceId = entity.InstanceId,
                OutNum = entity.OutNum,
                Reason = entity.Reason,
                Status = entity.Status,
                OutGoodsId = entity.OutGoodsId,
            };
        }

        public List<WorkFlowInstanceStepOutput> LoadStepEntities(string instanceId)
        {
            IQueryable<WorkFlowInstanceStep> iquery = _dbContext.Set<WorkFlowInstanceStep>().Where(u => u.InstanceId == instanceId);
            var linq = from a in iquery
                       join b in _dbContext.Set<UserInfo>() on a.ReviewerId equals b.UserId into join_a
                       from c in join_a.DefaultIfEmpty()
                       join d in _dbContext.Set<UserInfo>() on a.NextReviewerId equals d.UserId into join_b
                       from e in join_b.DefaultIfEmpty()
                       select new WorkFlowInstanceStepOutput
                       {
                           Id = a.Id,
                           InstanceId = a.InstanceId,
                           ReviewerId = a.ReviewerId,
                           ReviewReason = a.ReviewReason,
                           ReviewStatus = a.ReviewStatus,
                           ReviewTime = a.ReviewTime,
                           NextReviewerId = a.NextReviewerId,
                           ReviewerName = c.UserName,
                           NextReviewerName = e.UserName,
                       };
            return linq.ToList();
        }


        #region 耗材部分
        public bool ApplyConsumable(WorkFlowInstanceInput input)
        {
            //需要同时添加实例表和实例步骤表

            //【1】获取该用户的所有上级领导
            List<DepartmentParentOutput> bossList = _departmentService.GetReviewerMsg(input.UserId);
            //【2】添加实例表--打上标记
            string instanceId = input.UserId + DateTime.Now.ToString("yyyyMMddHHmmss");//因为userId是唯一的，且一个人不可能同一秒内提交两个请求，所以认为是唯一的，暂时不做重复验证


            if (bossList.Count == 2)
            {
                //---------非最高级别主管-------------
                WorkFlowInstance instanceEntity = new WorkFlowInstance
                {
                    Id = input.Id,
                    InstanceId = instanceId,
                    Description = input.Description,
                    OutGoodsId = input.OutGoodsId,
                    OutNum = input.OutNum,
                    Reason = input.Reason,
                    UserId = input.UserId,

                    AddTime = DateTime.Now,
                    ModelId = 2,//数据库中，2为耗材领取
                    Status = (int)MyEnum.ConsumableStatus.InReview,
                    NextReviewer = bossList[0].LeaderId,
                };

                _dbContext.Set<WorkFlowInstance>().Add(instanceEntity);


                //【3】计算总价
                GoodsConsumableInfo consumableEntity = _dbContext.Set<GoodsConsumableInfo>().Where(u => u.GoodsId == input.OutGoodsId).FirstOrDefault();
                float totalMoney = 0;
                if (consumableEntity.Money != null)
                {
                    totalMoney = (float)consumableEntity.Money * (float)input.OutNum;
                }

                //【4】添加步骤表
                List<WorkFlowInstanceStep> instanceStepList = new List<WorkFlowInstanceStep>();
                if (input.OutNum < 10 && totalMoney < 1000)
                {
                    //只需一级主管签核即可（如果用户就锁一级主管，则需要自己去签核）
                    WorkFlowInstanceStep instanceStepEntity = new WorkFlowInstanceStep
                    {
                        Id = 0,
                        InstanceId = instanceEntity.InstanceId,
                        ReviewerId = bossList[0].LeaderId,
                        NextReviewerId = "无",
                        ReviewStatus = (int)MyEnum.ReviewStatus.UnReview,
                    };
                    instanceStepList.Add(instanceStepEntity);
                }
                else
                {
                    //需一级主管和二级主管签核
                    int bossLength = bossList.Count;
                    for (int i = 0; i < bossLength; i++)
                    {
                        WorkFlowInstanceStep instanceStepEntity = new WorkFlowInstanceStep
                        {
                            Id = 0,
                            InstanceId = instanceEntity.InstanceId,
                            ReviewerId = bossList[i].LeaderId,
                            NextReviewerId = i < (bossLength - 1) ? bossList[i + 1].LeaderId : "无",
                            ReviewStatus = (int)MyEnum.ReviewStatus.UnReview,
                        };
                        instanceStepList.Add(instanceStepEntity);
                    }
                }

                _dbContext.Set<WorkFlowInstanceStep>().AddRange(instanceStepList);
            }
            else
            {
                //---------如果bossList.Count == 1,则说明是最高级别的主管-------------
                WorkFlowInstance instanceEntity = new WorkFlowInstance
                {
                    Id = input.Id,
                    InstanceId = instanceId,
                    Description = input.Description,
                    OutGoodsId = input.OutGoodsId,
                    OutNum = input.OutNum,
                    Reason = input.Reason,
                    UserId = input.UserId,

                    AddTime = DateTime.Now,
                    ModelId = 2,//数据库中，2为耗材领取
                    Status = (int)MyEnum.ConsumableStatus.IsPass,//最高主管不需要再审核
                    NextReviewer = input.UserId,
                };
                WorkFlowInstanceStep stepEntity = new WorkFlowInstanceStep
                {
                    Id = 0,
                    InstanceId = instanceEntity.InstanceId,
                    ReviewerId = instanceEntity.UserId,
                    NextReviewerId = "无",
                    ReviewTime = DateTime.Now,//自动签核
                    ReviewStatus = (int)MyEnum.ReviewStatus.IsPass,//最高主管自动通过
                };
                _dbContext.Set<WorkFlowInstance>().Add(instanceEntity);
                _dbContext.Set<WorkFlowInstanceStep>().Add(stepEntity);
            }


            //【5】内置事务统一提交
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool ReviewConsumable(string instanceId, string reviewerId, bool isPass, string reason)
        {
            //【1】修改步骤表
            WorkFlowInstanceStep stepEntity = _dbContext.Set<WorkFlowInstanceStep>().Where(u => u.InstanceId == instanceId && u.ReviewerId == reviewerId).FirstOrDefault();
            WorkFlowInstance instanceEntity = _dbContext.Set<WorkFlowInstance>().Where(u => u.InstanceId == instanceId).FirstOrDefault();
            stepEntity.ReviewTime = DateTime.Now;
            stepEntity.ReviewReason = reason;
            if (isPass)
            {
                if (stepEntity.NextReviewerId == "无")
                {
                    //审核通过，可以出库
                    stepEntity.ReviewStatus = (int)MyEnum.ReviewStatus.IsPass;
                    instanceEntity.Status = (int)MyEnum.ConsumableStatus.IsPass;
                    //instanceEntity.NextReviewer = "无";
                }
                else
                {
                    //审核通过，等待下一主管签核
                    stepEntity.ReviewStatus = (int)MyEnum.ReviewStatus.IsPass;
                    instanceEntity.NextReviewer = stepEntity.NextReviewerId;
                }
            }
            else
            {
                //驳回申请
                stepEntity.ReviewStatus = (int)MyEnum.ReviewStatus.IsRefused;
                instanceEntity.Status = (int)MyEnum.ConsumableStatus.IsRefused;
            }
            //【3】内置事务提交
            _dbContext.Attach(stepEntity);
            _dbContext.Update(stepEntity);
            _dbContext.Attach(instanceEntity);
            _dbContext.Update(instanceEntity);
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool RevokeConsumable(int Id)
        {
            //先查，再改
            WorkFlowInstance entity = _dbContext.Set<WorkFlowInstance>().Find(Id);
            entity.Status = (int)MyEnum.ConsumableStatus.IsRevoke;
            _dbContext.Attach(entity);
            _dbContext.Update(entity);
            return _dbContext.SaveChanges() > 0;
        }

        public bool OutpuConsumable(string arrInstance, string reviewerId)
        {
            //【1】分割字符串，获取所有实例编号
            string[] arr = arrInstance.Split(',');
            //【2】循环，并修改实例表和添加实例步骤表记录,同时减掉库存
            for (int i = 0; i < arr.Length - 1; i++)
            {
                WorkFlowInstance instanceEntity = _dbContext.Set<WorkFlowInstance>().Where(u => u.InstanceId == arr[i]).FirstOrDefault();

                instanceEntity.Status = (int)MyEnum.ConsumableStatus.IsOutput;
                instanceEntity.NextReviewer = reviewerId;
                //减掉库存
                GoodsConsumableInfo consumableEntity = _dbContext.Set<GoodsConsumableInfo>().Where(u => u.GoodsId == instanceEntity.OutGoodsId).FirstOrDefault();
                consumableEntity.Num -= instanceEntity.OutNum;
                WorkFlowInstanceStep stepEntity = new WorkFlowInstanceStep
                {
                    Id = 0,
                    InstanceId = arr[i],
                    NextReviewerId = "无",
                    ReviewStatus = (int)MyEnum.ReviewStatus.IsPass,
                    ReviewTime = DateTime.Now,
                    ReviewerId = reviewerId,
                    ReviewReason = "出库",
                };

                _dbContext.Set<WorkFlowInstance>().Attach(instanceEntity);
                _dbContext.Set<WorkFlowInstance>().Update(instanceEntity);
                _dbContext.Set<GoodsConsumableInfo>().Attach(consumableEntity);
                _dbContext.Set<GoodsConsumableInfo>().Update(consumableEntity);
                _dbContext.Set<WorkFlowInstanceStep>().Add(stepEntity);
            }
            //【3】内置事务，提交操作
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion


        #region 非耗材部分
        public bool ApplyEquipment(WorkFlowInstanceInput input)
        {
            //需要同时添加实例表和实例步骤表

            //【1】获取该用户的所有上级领导
            List<DepartmentParentOutput> bossList = _departmentService.GetReviewerMsg(input.UserId);
            //【2】添加实例表--打上标记
            string instanceId = input.UserId + DateTime.Now.ToString("yyyyMMddHHmmss");//因为userId是唯一的，且一个人不可能同一秒内提交两个请求，所以认为是唯一的，暂时不做重复验证
            if (bossList.Count == 2)
            {
                //---------非最高级别主管-------------
                WorkFlowInstance instanceEntity = new WorkFlowInstance
                {
                    Id = input.Id,
                    InstanceId = instanceId,
                    Description = input.Description,
                    OutGoodsId = input.OutGoodsId,
                    OutNum = input.OutNum,
                    Reason = input.Reason,
                    UserId = input.UserId,

                    AddTime = DateTime.Now,
                    ModelId = 3,//数据库中，3为非耗材领取
                    Status = (int)MyEnum.EquipmentStatus.InReview,
                    NextReviewer = bossList[0].LeaderId,
                };

                _dbContext.Set<WorkFlowInstance>().Add(instanceEntity);
          
                //【3】添加步骤表
                List<WorkFlowInstanceStep> instanceStepList = new List<WorkFlowInstanceStep>();             
                //只需一级主管签核即可（如果用户就锁一级主管，则需要自己去签核）
                WorkFlowInstanceStep instanceStepEntity = new WorkFlowInstanceStep
                {
                    Id = 0,
                    InstanceId = instanceEntity.InstanceId,
                    ReviewerId = bossList[0].LeaderId,
                    NextReviewerId = "无",
                    ReviewStatus = (int)MyEnum.ReviewStatus.UnReview,
                };
                instanceStepList.Add(instanceStepEntity);

                _dbContext.Set<WorkFlowInstanceStep>().AddRange(instanceStepList);
            }
            else
            {
                //---------如果bossList.Count == 1,则说明是最高级别的主管-------------
                WorkFlowInstance instanceEntity = new WorkFlowInstance
                {
                    Id = input.Id,
                    InstanceId = instanceId,
                    Description = input.Description,
                    OutGoodsId = input.OutGoodsId,
                    OutNum = input.OutNum,
                    Reason = input.Reason,
                    UserId = input.UserId,

                    AddTime = DateTime.Now,
                    ModelId = 3,//数据库中，3为非耗材领取
                    Status = (int)MyEnum.EquipmentStatus.IsPass,//最高主管不需要再审核
                    NextReviewer = input.UserId,
                };
                WorkFlowInstanceStep stepEntity = new WorkFlowInstanceStep
                {
                    Id = 0,
                    InstanceId = instanceEntity.InstanceId,
                    ReviewerId = instanceEntity.UserId,
                    NextReviewerId = "无",
                    ReviewTime = DateTime.Now,//自动签核
                    ReviewStatus = (int)MyEnum.ReviewStatus.IsPass,//最高主管自动通过
                };
                _dbContext.Set<WorkFlowInstance>().Add(instanceEntity);
                _dbContext.Set<WorkFlowInstanceStep>().Add(stepEntity);
            }

            //【5】内置事务统一提交
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool ReviewEquipment(string instanceId, string reviewerId, bool isPass, string reason)
        {
            //【1】修改步骤表
            WorkFlowInstanceStep stepEntity = _dbContext.Set<WorkFlowInstanceStep>().Where(u => u.InstanceId == instanceId && u.ReviewerId == reviewerId).FirstOrDefault();
            WorkFlowInstance instanceEntity = _dbContext.Set<WorkFlowInstance>().Where(u => u.InstanceId == instanceId).FirstOrDefault();
            stepEntity.ReviewTime = DateTime.Now;
            stepEntity.ReviewReason = reason;
            if (isPass)
            {
               
                //审核通过，可以出库
                stepEntity.ReviewStatus = (int)MyEnum.ReviewStatus.IsPass;
                instanceEntity.Status = (int)MyEnum.EquipmentStatus.IsPass;
                //instanceEntity.NextReviewer = "无";
               
               
            }
            else
            {
                //驳回申请
                stepEntity.ReviewStatus = (int)MyEnum.ReviewStatus.IsRefused;
                instanceEntity.Status = (int)MyEnum.EquipmentStatus.IsRefused;
            }
            //【3】内置事务提交
            _dbContext.Attach(stepEntity);
            _dbContext.Update(stepEntity);
            _dbContext.Attach(instanceEntity);
            _dbContext.Update(instanceEntity);
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool RevokeEquipment(int Id)
        {
            //先查，再改
            WorkFlowInstance entity = _dbContext.Set<WorkFlowInstance>().Find(Id);
            entity.Status = (int)MyEnum.EquipmentStatus.IsRevoke;
            _dbContext.Attach(entity);
            _dbContext.Update(entity);
            return _dbContext.SaveChanges() > 0;
        }

        public bool OutputEquipment(string arrInstance, string reviewerId)
        {
            //【1】分割字符串，获取所有实例编号
            string[] arr = arrInstance.Split(',');
            //【2】循环，并修改实例表和添加实例步骤表记录,同时减掉库存
            for (int i = 0; i < arr.Length - 1; i++)
            {
                WorkFlowInstance instanceEntity = _dbContext.Set<WorkFlowInstance>().Where(u => u.InstanceId == arr[i]).FirstOrDefault();

                instanceEntity.Status = (int)MyEnum.EquipmentStatus.IsLent;
                instanceEntity.NextReviewer = reviewerId;
                //减掉库存
                GoodsEquipmentInfo equipmentEntity = _dbContext.Set<GoodsEquipmentInfo>().Where(u => u.GoodsId == instanceEntity.OutGoodsId).FirstOrDefault();
                equipmentEntity.Num -= instanceEntity.OutNum;
                WorkFlowInstanceStep stepEntity = new WorkFlowInstanceStep
                {
                    Id = 0,
                    InstanceId = arr[i],
                    NextReviewerId = "无",
                    ReviewStatus = (int)MyEnum.ReviewStatus.IsPass,
                    ReviewTime = DateTime.Now,
                    ReviewerId = reviewerId,
                    ReviewReason = "已借出",
                };

                _dbContext.Set<WorkFlowInstance>().Attach(instanceEntity);
                _dbContext.Set<WorkFlowInstance>().Update(instanceEntity);
                _dbContext.Set<GoodsEquipmentInfo>().Attach(equipmentEntity);
                _dbContext.Set<GoodsEquipmentInfo>().Update(equipmentEntity);
                _dbContext.Set<WorkFlowInstanceStep>().Add(stepEntity);
            }
            //【3】内置事务，提交操作
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool ReturnEquipment(string arrInstance, string reviewerId)
        {
            //【1】分割字符串，获取所有实例编号
            string[] arr = arrInstance.Split(',');
            //【2】循环，并修改实例表和添加实例步骤表记录,同时添加库存
            for (int i = 0; i < arr.Length - 1; i++)
            {
                WorkFlowInstance instanceEntity = _dbContext.Set<WorkFlowInstance>().Where(u => u.InstanceId == arr[i]).FirstOrDefault();

                instanceEntity.Status = (int)MyEnum.EquipmentStatus.IsReturn;
                instanceEntity.NextReviewer = reviewerId;
                //添加库存
                GoodsEquipmentInfo equipmentEntity = _dbContext.Set<GoodsEquipmentInfo>().Where(u => u.GoodsId == instanceEntity.OutGoodsId).FirstOrDefault();
                equipmentEntity.Num += instanceEntity.OutNum;
                WorkFlowInstanceStep stepEntity = new WorkFlowInstanceStep
                {
                    Id = 0,
                    InstanceId = arr[i],
                    NextReviewerId = "无",
                    ReviewStatus = (int)MyEnum.ReviewStatus.IsPass,
                    ReviewTime = DateTime.Now,
                    ReviewerId = reviewerId,
                    ReviewReason = "已归还",
                };

                _dbContext.Set<WorkFlowInstance>().Attach(instanceEntity);
                _dbContext.Set<WorkFlowInstance>().Update(instanceEntity);
                _dbContext.Set<GoodsEquipmentInfo>().Attach(equipmentEntity);
                _dbContext.Set<GoodsEquipmentInfo>().Update(equipmentEntity);
                _dbContext.Set<WorkFlowInstanceStep>().Add(stepEntity);
            }
            //【3】内置事务，提交操作
            if (_dbContext.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public List<WorkFlowInstanceOutput> LoadPageIsLentEquipment(int pageIndex, int pageSize, out int totalCount, string selectInfo)
        {
            IQueryable<WorkFlowInstance> iquery;
            if (string.IsNullOrEmpty(selectInfo))
            {
                totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsLent && u.ModelId == 3).Count();
                iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsLent && u.ModelId == 3).OrderBy(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            else
            {
                totalCount = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsLent && u.UserId == selectInfo && u.ModelId == 3).Count();
                iquery = _dbContext.Set<WorkFlowInstance>().Where(u => u.Status == (int)MyEnum.EquipmentStatus.IsLent && u.UserId == selectInfo && u.ModelId == 3).OrderBy(u => u.AddTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            var linq = from a in iquery
                       join b in _dbContext.Set<UserInfo>() on a.UserId equals b.UserId into join_a
                       from c in join_a.DefaultIfEmpty()
                       join d in _dbContext.Set<UserInfo>() on a.NextReviewer equals d.UserId into join_b
                       from e in join_b.DefaultIfEmpty()
                       join f in _dbContext.Set<WorkFlowModel>() on a.ModelId equals f.Id into join_c
                       from g in join_c.DefaultIfEmpty()
                       join h in _dbContext.Set<GoodsEquipmentInfo>() on a.OutGoodsId equals h.GoodsId into join_d
                       from i in join_d.DefaultIfEmpty()
                       select new WorkFlowInstanceOutput
                       {
                           Id = a.Id,
                           AddTime = a.AddTime,
                           Description = a.Description,
                           ModelId = a.ModelId,
                           ModelName = g.Title,
                           InstanceId = a.InstanceId,

                           UserId = a.UserId,
                           UserName = c.UserName,
                           NextReviewer = a.NextReviewer,
                           ReviewerName = e.UserName,
                           OutGoodsName = i.Name,
                           OutNum = a.OutNum,
                           Reason = a.Reason,
                           Status = a.Status,
                       };
            return linq.ToList();
        }
        #endregion
    }
}
